package com.example.ddd.application.service.impl;

import com.example.ddd.application.service.OrderApplicationService;
import com.example.ddd.domain.model.Order;
import com.example.ddd.domain.repository.OrderRepository;
import com.example.ddd.domain.service.OrderDomainService;
import com.example.ddd.domain.service.OrderLockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Optional;

/**
 * 订单应用服务实现类
 */
@Service
public class OrderApplicationServiceImpl implements OrderApplicationService {
    
    private final OrderRepository orderRepository;
    private final OrderDomainService orderDomainService;
    private final OrderLockService orderLockService;
    
    @Autowired
    public OrderApplicationServiceImpl(OrderRepository orderRepository, 
                                      OrderDomainService orderDomainService,
                                      OrderLockService orderLockService) {
        this.orderRepository = orderRepository;
        this.orderDomainService = orderDomainService;
        this.orderLockService = orderLockService;
    }
    
    @Override
    public String createOrder(String customerId) {
        Order order = new Order(customerId);
        Order savedOrder = orderRepository.save(order);
        return savedOrder.getId();
    }
    
    @Override
    public void addOrderItem(String orderId, String productId, int quantity, double price) {
        Order order = findOrderById(orderId);
        order.addItem(productId, quantity, price);
        orderRepository.save(order);
    }
    
    @Override
    public void submitOrder(String orderId) {
        Order order = findOrderById(orderId);
        orderDomainService.validateOrderBeforeSubmit(order);
        order.submit();
        orderRepository.save(order);
    }
    
    @Override
    public void payOrder(String orderId) {
        // 使用分布式锁保护支付操作
        boolean locked = orderLockService.tryLockOrderPayment(orderId);
        if (!locked) {
            throw new RuntimeException("订单支付操作正在进行中，请稍后再试");
        }
        
        try {
            Order order = findOrderById(orderId);
            order.pay();
            orderRepository.save(order);
        } finally {
            // 确保锁被释放
            orderLockService.releaseOrderPaymentLock(orderId);
        }
    }
    
    @Override
    public void cancelOrder(String orderId) {
        // 使用分布式锁保护取消操作
        boolean locked = orderLockService.tryLockOrderCancellation(orderId);
        if (!locked) {
            throw new RuntimeException("订单取消操作正在进行中，请稍后再试");
        }
        
        try {
            Order order = findOrderById(orderId);
            order.cancel();
            orderRepository.save(order);
        } finally {
            // 确保锁被释放
            orderLockService.releaseOrderCancellationLock(orderId);
        }
    }
    
    @Override
    public Order getOrder(String orderId) {
        return findOrderById(orderId);
    }
    
    // 辅助方法：根据ID查找订单，如果不存在则抛出异常
    private Order findOrderById(String orderId) {
        Optional<Order> orderOptional = orderRepository.findById(orderId);
        return orderOptional.orElseThrow(() -> 
            new IllegalArgumentException("找不到订单: " + orderId));
    }
}